#include "../arbol/ArbolBMas.h"
#include "../arbol/RegDatos.h"
#include "../arbol/RegIndice.h"
#include "../arbol/NodoDatos.h"
#include "../arbol/NodoIndice.h"
#include "../arbol/ArchivoBloques.h"
#include "../arbol/ClaveString.h"
#include "../arbol/ClaveInt.h"
#include "../arbol/DatoInt.h"
#include "../arbol/DatoString.h"
#include "testArbol.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <list>
#include <iostream>
#include <vector>


void testPartirIndice1(){
	
	///////////// NODO ÍNDICE //////////////////

	///// 1er reg

	char clave1 [] = "AABB";
	
	ClaveString* c1 = new ClaveString();
	
	(*c1).setClave(clave1);

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	
	///// 2do reg

	char clave2 [] = "AAAAA";
	
	ClaveString* c2 = new ClaveString();
	
	(*c2).setClave(clave2);

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);
	
	
	///// 3er reg

	char clave3 [] = "AAAAB";
	
	ClaveString* c3 = new ClaveString();
	
	(*c3).setClave(clave3);

	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS 1, 2 y 3

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg1,2);
	(*inodo).insertarRegEHijo(reg2,3);
	(*inodo).insertarRegEHijo(reg3,4);
	
	
	cout << " <<<<<<<<<< NODO INDICE ANTES DE PARTIRLO >>>>>>>>>>\n\n";
	(*inodo).imprimirBasico();
	cout << "\n";


	
	/////////// Nodo con el que se reparte ///////////
	
	NodoIndice<ClaveString,DatoInt>* npartir = new NodoIndice<ClaveString,DatoInt>();
	(*npartir).setNivel(2);
	
	////////////

	RegIndice<ClaveString,DatoInt>* subir = (*inodo).partir(npartir);
	
	
	cout << " <<<<<<<<<< NODO INDICE PARTIDO >>>>>>>>>>\n\n";
	(*inodo).imprimirBasico();
	
	cout << "\n";
	
	cout << "--- Registro que sube al padre: " << *((*subir).getClave()) << "\n\n\n";
	
	cout << " <<<<<<<<<< NUEVO NODO INDICE >>>>>>>>>>\n\n";
	(*npartir).imprimirBasico();
	cout << "\n\n";
	
	delete subir;
	delete inodo;
	delete npartir;


}

void testPartirIndice2(){
	
	///////////// NODO ÍNDICE //////////////////

	///// 1er reg

	char clave1 [] = "AABB";
	
	ClaveString* c1 = new ClaveString();
	
	(*c1).setClave(clave1);

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	
	///// 2do reg

	char clave2 [] = "AAA";
	
	ClaveString* c2 = new ClaveString();
	
	(*c2).setClave(clave2);

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);
	
	
	///// 3er reg

	char clave3 [] = "AAAAB";
	
	ClaveString* c3 = new ClaveString();
	
	(*c3).setClave(clave3);

	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS 1, 2 y 3

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg1,2);
	(*inodo).insertarRegEHijo(reg2,3);
	(*inodo).insertarRegEHijo(reg3,4);
	
	
	cout << " <<<<<<<<<< NODO INDICE ANTES DE PARTIRLO >>>>>>>>>>\n\n";
	(*inodo).imprimirBasico();
	cout << "\n";


	
	/////////// Nodo con el que se reparte ///////////
	
	NodoIndice<ClaveString,DatoInt>* npartir = new NodoIndice<ClaveString,DatoInt>();
	(*npartir).setNivel(2);
	
	////////////

	RegIndice<ClaveString,DatoInt>* subir = (*inodo).partir(npartir);
	
	
	cout << " <<<<<<<<<< NODO INDICE PARTIDO >>>>>>>>>>\n\n";
	(*inodo).imprimirBasico();
	
	cout << "\n";
	
	cout << "--- Registro que sube al padre: " << *((*subir).getClave()) << "\n\n\n";
	
	cout << " <<<<<<<<<< NUEVO NODO INDICE >>>>>>>>>>\n\n";
	(*npartir).imprimirBasico();
	cout << "\n\n";
	
	delete subir;
	delete inodo;
	delete npartir;	
	
}

void testPartirDatos1(){

	///////////////// NODO DATOS //////////////////

	///// 1er reg


	char clave1 [] = "ABCD";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "AABBCC";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "ABAB";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2 Y reg3

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);
	
	cout << " <<<<<<<<<< NODO DE DATOS ANTES DE PARTIRLO >>>>>>>>>>\n\n";
	(*dnodo).imprimirBasico();
	
	
	
	/////////// Nodo con el que se reparte ///////////
	
	NodoDatos<ClaveString,DatoInt>* npartir = new NodoDatos<ClaveString,DatoInt>();
	
	(*npartir).setSiguiente(7);
	
	///////////////

	(*dnodo).partir(npartir);
	
	cout << " <<<<<<<<<< NODO DE DATOS PARTIDO >>>>>>>>>>\n\n";
	(*dnodo).imprimirBasico();
	
	cout << " <<<<<<<<<< NUEVO NODO DE DATOS >>>>>>>>>>\n\n";
	(*npartir).imprimirBasico();
	
	delete dnodo;
	delete npartir;
	
	cout <<"\n\n";
		
	
}

void testPartirDatos2(){
	
	///////////////// NODO DATOS //////////////////

	///// 1er reg


	char clave1 [] = "ABCD";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "AA";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "ABAB";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2 Y reg3

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);
	
	cout << " <<<<<<<<<< NODO DE DATOS ANTES DE PARTIRLO >>>>>>>>>>\n\n";
	(*dnodo).imprimirBasico();
	
	
	
	/////////// Nodo con el que se reparte ///////////
	
	NodoDatos<ClaveString,DatoInt>* npartir = new NodoDatos<ClaveString,DatoInt>();
	
	(*npartir).setSiguiente(7);
	
	///////////////

	(*dnodo).partir(npartir);
	
	cout << " <<<<<<<<<< NODO DE DATOS PARTIDO >>>>>>>>>>\n\n";
	(*dnodo).imprimirBasico();
	
	cout << " <<<<<<<<<< NUEVO NODO DE DATOS >>>>>>>>>>\n\n";
	(*npartir).imprimirBasico();
	
	delete dnodo;
	delete npartir;
	
	cout <<"\n\n";
		
	
}	
	
void testSerializarYDesserializarNodoDatos(){

	///////////////// NODO DATOS //////////////////

	///// 1er reg


	char clave1 [] = "ABCD";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "AA";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "ABAB";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2 Y reg3

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);	
	
	
	cout << "NODO DE DATOS ORIGINAL:\n";
	(*dnodo).imprimirBasico();
	
	
	/** Buffer para serializar **/
	
	char* buffer = (char*)calloc(100, sizeof(char));
	
	(*dnodo).serializar(buffer);
	
	/****************************/
	
	
	/** Nodo para recuperar el serializado anteriormente (desserializar) **/
	
	NodoDatos<ClaveString,DatoInt>* nodoRecup = new NodoDatos<ClaveString,DatoInt>();
		
	(*nodoRecup).desSerializar(buffer);
	
	/****************************/
	
	
	cout << "NODO DE DATOS RECUPERADO: \n";
	(*nodoRecup).imprimirBasico();
	
	delete dnodo;
	delete nodoRecup;
	free (buffer);
}	

void testSerializarYDesserializarNodoIndice(){
	
	///////////// NODO ÍNDICE //////////////////

	///// 1er reg

	char clave1 [] = "AABB";
	
	ClaveString* c1 = new ClaveString();
	
	(*c1).setClave(clave1);

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	
	///// 2do reg

	char clave2 [] = "AAAAA";
	
	ClaveString* c2 = new ClaveString();
	
	(*c2).setClave(clave2);

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);
	
	
	///// 3er reg

	char clave3 [] = "AAAAB";
	
	ClaveString* c3 = new ClaveString();
	
	(*c3).setClave(clave3);

	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS 1, 2 y 3

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg1,2);
	(*inodo).insertarRegEHijo(reg2,3);
	(*inodo).insertarRegEHijo(reg3,4);
	
	
	cout << "NODO INDICE ORIGINAL:\n";
	(*inodo).imprimirBasico();
	
	
	/** Buffer para serializar **/
	
	char* buffer = (char*)calloc(100, sizeof(char));
	
	(*inodo).serializar(buffer);
	
	/****************************/
	
	
	/** Nodo para recuperar el serializado anteriormente (desserializar) **/
	
	NodoIndice<ClaveString,DatoInt>* nodoRecup = new NodoIndice<ClaveString,DatoInt>();
		
	(*nodoRecup).desSerializar(buffer);
	
	/****************************/
	
	
	cout << "NODO INDICE RECUPERADO: \n";
	(*nodoRecup).imprimirBasico();
	
	delete inodo;
	delete nodoRecup;
	free (buffer);
}	

void testBalancearNodoDatosConIzquierdo(){
	
	///////////////// NODO DATOS IZQUIERDO (para balancear) //////////////////

	///// 1er reg


	char clave1 [] = "B";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "C";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "D";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2, reg3 y reg4

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);



	///////////////// NODO DATOS CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "G";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	
	DatoInt* c4_d1 = new DatoInt();
	(*c4_d1).setDato(7);
	
	DatoInt* c4_d2 = new DatoInt();
	(*c4_d2).setDato(8);
	
	DatoInt* c4_d3 = new DatoInt();
	(*c4_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg4 = new RegDatos<ClaveString,DatoInt>();

	(*reg4).setClave(c4);

	(*reg4).cargarDato(c4_d1);
	(*reg4).cargarDato(c4_d2);
	(*reg4).cargarDato(c4_d3);


				
	// CREO EL NODO DE DATOS CON EL REG reg4

	NodoDatos<ClaveString,DatoInt>* dnodo2 = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo2).setSiguiente(5);
	
	(*dnodo2).insertarRegOrdenado(reg4);
	
	
	
	
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "A";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "H";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);	
	
/*** Impresión de los nodos inicialmente ***/
	
	cout << "Hermano izquierdo para balancear:\n";	
	(*dnodo).imprimirBasico();		
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();

	if ((*dnodo2).quedoEnUnderflow(80)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 50\n";
	}
	
	(*dnodo2).imprimirBasico();	
	
/********************************************/

	/*** BALANCEAMOS **/
	(*dnodo2).balancearConIzquierdo(dnodo, inodo, 80);	
	/*****/
	
	cout << "Hermano izquierdo luego de balancear:\n";
	(*dnodo).imprimirBasico();
	
	cout << "Nodo padre luego de balancear:\n";
	(*inodo).imprimirBasico();
	
	cout << "Nodo con underflow luego de balancear:\n";
	(*dnodo2).imprimirBasico();
	
	if (!(*dnodo).quedoEnUnderflow(80)){
		cout << "El hermano izq. quedó en estado válido\n";
	}
	
	if (!(*inodo).quedoEnUnderflow(80)){
		cout << "El padre quedó en estado válido\n";
	}
	
	if (!(*dnodo2).quedoEnUnderflow(80)){
		cout << "El nodo que tenía underflow quedó en estado válido\n";
	}			
	
	delete dnodo;
	delete inodo;
	delete dnodo2;
	
}	

void testBalancearNodoDatosConDerecho(){

	///////////////// NODO DATOS DERECHO (para balancear) //////////////////

	///// 1er reg


	char clave1 [] = "G";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "H";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "I";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	
	
	///// 4to reg
	
	char clave5 [] = "J";
	
	ClaveString* c5 = new ClaveString();
	(*c5).setClave(clave5);
	
	DatoInt* c5_d1 = new DatoInt();
	(*c5_d1).setDato(4);
	
	DatoInt* c5_d2 = new DatoInt();
	(*c5_d2).setDato(5);
	
	DatoInt* c5_d3 = new DatoInt();
	(*c5_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg5 = new RegDatos<ClaveString,DatoInt>();

	(*reg5).setClave(c5);

	(*reg5).cargarDato(c5_d1);
	(*reg5).cargarDato(c5_d2);
	(*reg5).cargarDato(c5_d3);	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2, reg3 y reg4

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);
	
	(*dnodo).insertarRegOrdenado(reg5);	



	///////////////// NODO DATOS CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "E";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	
	DatoInt* c4_d1 = new DatoInt();
	(*c4_d1).setDato(7);
	
	DatoInt* c4_d2 = new DatoInt();
	(*c4_d2).setDato(8);
	
	DatoInt* c4_d3 = new DatoInt();
	(*c4_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg4 = new RegDatos<ClaveString,DatoInt>();

	(*reg4).setClave(c4);

	(*reg4).cargarDato(c4_d1);
	(*reg4).cargarDato(c4_d2);
	(*reg4).cargarDato(c4_d3);


				
	// CREO EL NODO DE DATOS CON EL REG reg4

	NodoDatos<ClaveString,DatoInt>* dnodo2 = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo2).setSiguiente(5);
	
	(*dnodo2).insertarRegOrdenado(reg4);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "D";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "K";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);
	
/*** Impresión de los nodos inicialmente ***/
	
	if ((*dnodo2).quedoEnUnderflow(80)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 80\n";
	}
	
	(*dnodo2).imprimirBasico();	
	
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();
			
	
	cout << "Hermano derecho para balancear:\n";	
	(*dnodo).imprimirBasico();		

	
/********************************************/	


	/*** BALANCEAMOS **/
	(*dnodo2).balancearConDerecho(dnodo, inodo, 80);	
	/*****/
	
	
	cout << "Nodo con underflow luego de balancear:\n";
	(*dnodo2).imprimirBasico();			
	
	cout << "Nodo padre luego de balancear:\n";
	(*inodo).imprimirBasico();	
	
	cout << "Hermano derecho luego de balancear:\n";
	(*dnodo).imprimirBasico();


	
	if (!(*dnodo2).quedoEnUnderflow(80)){
		cout << "El nodo que tenía underflow quedó en estado válido\n";
	}	

	
	if (!(*inodo).quedoEnUnderflow(80)){
		cout << "El padre quedó en estado válido\n";
	}


	if (!(*dnodo).quedoEnUnderflow(80)){
		cout << "El hermano dcho. quedó en estado válido\n";
	}

	delete dnodo;
	delete dnodo2;
	delete inodo;
	
}	
	
void testFusionarNodoDatosConIzquierdo(){


	///////////////// NODO DATOS IZQUIERDO (para fusionar) //////////////////

	///// 1er reg


	char clave1 [] = "B";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "C";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "D";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2, reg3 y reg4

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);



	///////////////// NODO DATOS CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "G";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	
	DatoInt* c4_d1 = new DatoInt();
	(*c4_d1).setDato(7);
	
	DatoInt* c4_d2 = new DatoInt();
	(*c4_d2).setDato(8);
	
	DatoInt* c4_d3 = new DatoInt();
	(*c4_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg4 = new RegDatos<ClaveString,DatoInt>();

	(*reg4).setClave(c4);

	(*reg4).cargarDato(c4_d1);
	(*reg4).cargarDato(c4_d2);
	(*reg4).cargarDato(c4_d3);


				
	// CREO EL NODO DE DATOS CON EL REG reg4

	NodoDatos<ClaveString,DatoInt>* dnodo2 = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo2).setSiguiente(5);
	
	(*dnodo2).insertarRegOrdenado(reg4);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "A";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "H";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);
	
	
	
/*** Impresión de los nodos inicialmente ***/
	
	cout << "Hermano izquierdo fusionar:\n";	
	(*dnodo).imprimirBasico();		
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();

	if ((*dnodo2).quedoEnUnderflow(80)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 80\n";
	}
	
	(*dnodo2).imprimirBasico();	
	
/********************************************/

	/*** FUSIONAMOS **/
	(*dnodo2).fusionarConIzquierdo(dnodo, inodo);	
	/*****/
	
	cout << "Hermano izquierdo luego de fusionar:\n";
	(*dnodo).imprimirBasico();
	
	cout << "Nodo padre luego de fusionar:\n";
	(*inodo).imprimirBasico();
	
	cout << "Nodo con underflow luego de fusionar:\n";
	(*dnodo2).imprimirBasico();
	
	if (!(*dnodo).quedoEnUnderflow(80)){
		cout << "El hermano izq. quedó en estado válido\n";
	}
	
	if ((*inodo).quedoEnUnderflow(80)){
		cout << "El padre quedó en underflow\n";
	}
	
	if ((*dnodo2).getNReg() == 0){
		cout << "El nodo que tenía underflow quedó vacío (se pasó todo al izquierdo)\n";
	}			
	
	delete dnodo;
	delete inodo;
	delete dnodo2;	
	
}		

void testFusionarNodoDatosConDerecho(){
	
	///////////////// NODO DATOS DERECHO (para fusionar) //////////////////

	///// 1er reg


	char clave1 [] = "G";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
	
	DatoInt* c1_d1 = new DatoInt();
	(*c1_d1).setDato(7);
	
	DatoInt* c1_d2 = new DatoInt();
	(*c1_d2).setDato(8);
	
	DatoInt* c1_d3 = new DatoInt();
	(*c1_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();

	(*reg1).setClave(c1);

	(*reg1).cargarDato(c1_d1);
	(*reg1).cargarDato(c1_d2);
	(*reg1).cargarDato(c1_d3);

	
	
	
	///// 2do reg

	char clave2 [] = "H";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	
	DatoInt* c2_d1 = new DatoInt();
	(*c2_d1).setDato(1);
	
	DatoInt* c2_d2 = new DatoInt();
	(*c2_d2).setDato(2);
	
	DatoInt* c2_d3 = new DatoInt();
	(*c2_d3).setDato(3);
	
	

	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();

	(*reg2).setClave(c2);

	(*reg2).cargarDato(c2_d1);
	(*reg2).cargarDato(c2_d2);
	(*reg2).cargarDato(c2_d3);


	///// 3er reg
	
	char clave3 [] = "I";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	
	DatoInt* c3_d1 = new DatoInt();
	(*c3_d1).setDato(4);
	
	DatoInt* c3_d2 = new DatoInt();
	(*c3_d2).setDato(5);
	
	DatoInt* c3_d3 = new DatoInt();
	(*c3_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	(*reg3).cargarDato(c3_d1);
	(*reg3).cargarDato(c3_d2);
	(*reg3).cargarDato(c3_d3);
	
	
	///// 4to reg
	
	char clave5 [] = "J";
	
	ClaveString* c5 = new ClaveString();
	(*c5).setClave(clave5);
	
	DatoInt* c5_d1 = new DatoInt();
	(*c5_d1).setDato(4);
	
	DatoInt* c5_d2 = new DatoInt();
	(*c5_d2).setDato(5);
	
	DatoInt* c5_d3 = new DatoInt();
	(*c5_d3).setDato(6);
	
	

	RegDatos<ClaveString,DatoInt>* reg5 = new RegDatos<ClaveString,DatoInt>();

	(*reg5).setClave(c5);

	(*reg5).cargarDato(c5_d1);
	(*reg5).cargarDato(c5_d2);
	(*reg5).cargarDato(c5_d3);	

	
				
	// CREO EL NODO DE DATOS CON LOS REG reg1, reg2, reg3 y reg4

	NodoDatos<ClaveString,DatoInt>* dnodo = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo).setSiguiente(5);
	
	(*dnodo).insertarRegOrdenado(reg1);
	
	(*dnodo).insertarRegOrdenado(reg2);

	(*dnodo).insertarRegOrdenado(reg3);
	
	(*dnodo).insertarRegOrdenado(reg5);	



	///////////////// NODO DATOS CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "E";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	
	DatoInt* c4_d1 = new DatoInt();
	(*c4_d1).setDato(7);
	
	DatoInt* c4_d2 = new DatoInt();
	(*c4_d2).setDato(8);
	
	DatoInt* c4_d3 = new DatoInt();
	(*c4_d3).setDato(9);
	
	

	RegDatos<ClaveString,DatoInt>* reg4 = new RegDatos<ClaveString,DatoInt>();

	(*reg4).setClave(c4);

	(*reg4).cargarDato(c4_d1);
	(*reg4).cargarDato(c4_d2);
	(*reg4).cargarDato(c4_d3);


				
	// CREO EL NODO DE DATOS CON EL REG reg4

	NodoDatos<ClaveString,DatoInt>* dnodo2 = new NodoDatos<ClaveString,DatoInt>();


	(*dnodo2).setSiguiente(5);
	
	(*dnodo2).insertarRegOrdenado(reg4);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "D";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "K";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);	
	
	
	
/*** Impresión de los nodos inicialmente ***/

	if ((*dnodo2).quedoEnUnderflow(80)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 80\n";
	}
	(*dnodo2).imprimirBasico();		
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();
	
			
	cout << "Hermano derecho fusionar:\n";	
	(*dnodo).imprimirBasico();		
	
	
/********************************************/

	/*** FUSIONAMOS **/
	(*dnodo2).fusionarConDerecho(dnodo, inodo);	
	/*****/
	
	cout << "Nodo con underflow luego de fusionar:\n";
	(*dnodo2).imprimirBasico();	
	
	
	cout << "Nodo padre luego de fusionar:\n";
	(*inodo).imprimirBasico();	
	
	cout << "Hermano derecho luego de fusionar:\n";
	(*dnodo).imprimirBasico();
	
	
	if (!(*dnodo2).quedoEnUnderflow(80)){
		cout << "El nodo que tenía underflow quedó en estado válido\n";
	}
	
	if ((*inodo).quedoEnUnderflow(80)){
		cout << "El padre quedó en underflow\n";
	}
	
	if ((*dnodo).getNReg() == 0){
		cout << "El hermano derecho quedó vacío (se pasó todo al izquierdo)\n";
	}			
	
	delete dnodo;
	delete inodo;
	delete dnodo2;		
	
}
	
void testBalancearNodoIndiceConIzquierdo(){
	
	///////////////// NODO INDICE IZQUIERDO (para balancear) //////////////////

	///// 1er reg


	char clave1 [] = "B";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
		

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);
	
	
	
	///// 2do reg

	char clave2 [] = "C";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);



	///// 3er reg
	
	char clave3 [] = "D";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	


	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	
	///// 4to reg
	
	char clave5 [] = "E";
	
	ClaveString* c5 = new ClaveString();
	(*c5).setClave(clave5);
		

	RegIndice<ClaveString,DatoInt>* reg5 = new RegIndice<ClaveString,DatoInt>();

	(*reg5).setClave(c5);


				
	// CREO EL NODO INDICE CON LOS REG reg1, reg2, reg3 y reg5

	NodoIndice<ClaveString,DatoInt>* inodoBal = new NodoIndice<ClaveString,DatoInt>();

	(*inodoBal).setNivel(1);

	(*inodoBal).agregarNHijo(8);

	(*inodoBal).insertarRegEHijo(reg1,1);
	(*inodoBal).insertarRegEHijo(reg2,5);
	(*inodoBal).insertarRegEHijo(reg3,9);	
	(*inodoBal).insertarRegEHijo(reg5,6);	



	///////////////// NODO INDICE CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "G";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	


	RegIndice<ClaveString,DatoInt>* reg4 = new RegIndice<ClaveString,DatoInt>();

	(*reg4).setClave(c4);


				
	// CREO EL NODO DE INDICE CON EL REG reg4

	NodoIndice<ClaveString,DatoInt>* inodoUnd = new NodoIndice<ClaveString,DatoInt>();

	(*inodoUnd).setNivel(1);

	(*inodoUnd).agregarNHijo(2);

	(*inodoUnd).insertarRegEHijo(reg4,10);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "A";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "H";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);


	///// 4to reg

	char clave9 [] = "L";
	
	ClaveString* c9 = new ClaveString();
	
	(*c9).setClave(clave9);

	RegIndice<ClaveString,DatoInt>* reg9 = new RegIndice<ClaveString,DatoInt>();

	(*reg9).setClave(c9);	
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);	
	(*inodo).insertarRegEHijo(reg9,5);
	
/*** Impresión de los nodos inicialmente ***/
	
	cout << "Hermano izquierdo para balancear:\n";	
	(*inodoBal).imprimirBasico();		
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();

	if ((*inodoUnd).quedoEnUnderflow(50)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 80\n";
	}
	
	(*inodoUnd).imprimirBasico();	
	
/********************************************/

	/*** BALANCEAMOS **/
	(*inodoUnd).balancearConIzquierdo(inodoBal, inodo, 50);	
	/*****/
	
	cout << "Hermano izquierdo luego de balancear:\n";
	(*inodoBal).imprimirBasico();
	
	cout << "Nodo padre luego de balancear:\n";
	(*inodo).imprimirBasico();
	
	cout << "Nodo con underflow luego de balancear:\n";
	(*inodoUnd).imprimirBasico();
	
	if (!(*inodoBal).quedoEnUnderflow(50)){
		cout << "El hermano izq. quedó en estado válido\n";
	}
	
	if (!(*inodo).quedoEnUnderflow(50)){
		cout << "El padre quedó en estado válido\n";
	}
	
	if (!(*inodoUnd).quedoEnUnderflow(50)){
		cout << "El nodo que tenía underflow quedó en estado válido\n";
	}			
	
	delete inodoBal;
	delete inodo;
	delete inodoUnd;

	
	
}	

void testBalancearNodoIndiceConDerecho(){

	///////////////// NODO INDICE DERECHO (para balancear) //////////////////

	///// 1er reg


	char clave1 [] = "G";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
		

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);
	
	
	
	///// 2do reg

	char clave2 [] = "H";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);



	///// 3er reg
	
	char clave3 [] = "I";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	


	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	
	///// 4to reg
	
	char clave5 [] = "J";
	
	ClaveString* c5 = new ClaveString();
	(*c5).setClave(clave5);
		

	RegIndice<ClaveString,DatoInt>* reg5 = new RegIndice<ClaveString,DatoInt>();

	(*reg5).setClave(c5);


				
	// CREO EL NODO INDICE CON LOS REG reg1, reg2, reg3 y reg5

	NodoIndice<ClaveString,DatoInt>* inodoBal = new NodoIndice<ClaveString,DatoInt>();

	(*inodoBal).setNivel(1);

	(*inodoBal).agregarNHijo(8);

	(*inodoBal).insertarRegEHijo(reg1,1);
	(*inodoBal).insertarRegEHijo(reg2,5);
	(*inodoBal).insertarRegEHijo(reg3,9);	
	(*inodoBal).insertarRegEHijo(reg5,6);	



	///////////////// NODO INDICE CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "E";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	


	RegIndice<ClaveString,DatoInt>* reg4 = new RegIndice<ClaveString,DatoInt>();

	(*reg4).setClave(c4);


				
	// CREO EL NODO DE INDICE CON EL REG reg4

	NodoIndice<ClaveString,DatoInt>* inodoUnd = new NodoIndice<ClaveString,DatoInt>();

	(*inodoUnd).setNivel(1);

	(*inodoUnd).agregarNHijo(2);

	(*inodoUnd).insertarRegEHijo(reg4,10);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "D";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "K";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);


	///// 4to reg

	char clave9 [] = "L";
	
	ClaveString* c9 = new ClaveString();
	
	(*c9).setClave(clave9);

	RegIndice<ClaveString,DatoInt>* reg9 = new RegIndice<ClaveString,DatoInt>();

	(*reg9).setClave(c9);	
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);	
	(*inodo).insertarRegEHijo(reg9,5);


/*** Impresión de los nodos inicialmente ***/
	
	if ((*inodoUnd).quedoEnUnderflow(50)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 50\n";
	}
	
	(*inodoUnd).imprimirBasico();	
	
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();
			
	
	cout << "Hermano derecho para balancear:\n";	
	(*inodoBal).imprimirBasico();		

	
/********************************************/	


	/*** BALANCEAMOS **/
	(*inodoUnd).balancearConDerecho(inodoBal, inodo, 50);	
	/*****/
	
	
	cout << "Nodo con underflow luego de balancear:\n";
	(*inodoUnd).imprimirBasico();			
	
	cout << "Nodo padre luego de balancear:\n";
	(*inodo).imprimirBasico();	
	
	cout << "Hermano derecho luego de balancear:\n";
	(*inodoBal).imprimirBasico();


	
	if (!(*inodoUnd).quedoEnUnderflow(50)){
		cout << "El nodo que tenía underflow quedó en estado válido\n";
	}	

	
	if (!(*inodo).quedoEnUnderflow(50)){
		cout << "El padre quedó en estado válido\n";
	}


	if (!(*inodoBal).quedoEnUnderflow(50)){
		cout << "El hermano dcho. quedó en estado válido\n";
	}

	delete inodoUnd;
	delete inodo;
	delete inodoBal;	
	
		
}

void testFusionarNodoIndiceConIzquierdo(){
	
	///////////////// NODO INDICE IZQUIERDO (para fusionar) //////////////////

	///// 1er reg


	char clave1 [] = "B";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
		

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);
	
	
	
	///// 2do reg

	char clave2 [] = "C";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);



	///// 3er reg
	
	char clave3 [] = "D";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	


	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	
	///// 4to reg
	
	char clave5 [] = "E";
	
	ClaveString* c5 = new ClaveString();
	(*c5).setClave(clave5);
		

	RegIndice<ClaveString,DatoInt>* reg5 = new RegIndice<ClaveString,DatoInt>();

	(*reg5).setClave(c5);


				
	// CREO EL NODO INDICE CON LOS REG reg1, reg2, reg3 y reg5

	NodoIndice<ClaveString,DatoInt>* inodoFus = new NodoIndice<ClaveString,DatoInt>();

	(*inodoFus).setNivel(1);

	(*inodoFus).agregarNHijo(8);

	(*inodoFus).insertarRegEHijo(reg1,1);
	(*inodoFus).insertarRegEHijo(reg2,5);
	(*inodoFus).insertarRegEHijo(reg3,9);	
	(*inodoFus).insertarRegEHijo(reg5,6);	



	///////////////// NODO INDICE CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "G";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	


	RegIndice<ClaveString,DatoInt>* reg4 = new RegIndice<ClaveString,DatoInt>();

	(*reg4).setClave(c4);


				
	// CREO EL NODO DE INDICE CON EL REG reg4

	NodoIndice<ClaveString,DatoInt>* inodoUnd = new NodoIndice<ClaveString,DatoInt>();

	(*inodoUnd).setNivel(1);

	(*inodoUnd).agregarNHijo(2);

	(*inodoUnd).insertarRegEHijo(reg4,10);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "A";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "H";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);


	///// 4to reg

	char clave9 [] = "L";
	
	ClaveString* c9 = new ClaveString();
	
	(*c9).setClave(clave9);

	RegIndice<ClaveString,DatoInt>* reg9 = new RegIndice<ClaveString,DatoInt>();

	(*reg9).setClave(c9);	
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);	
	(*inodo).insertarRegEHijo(reg9,5);


	
/*** Impresión de los nodos inicialmente ***/
	
	cout << "Hermano izquierdo fusionar:\n";	
	(*inodoFus).imprimirBasico();		
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();

	if ((*inodoUnd).quedoEnUnderflow(50)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 50\n";
	}
	
	(*inodoUnd).imprimirBasico();	
	
/********************************************/

	/*** FUSIONAMOS **/
	(*inodoUnd).fusionarConIzquierdo(inodoFus, inodo);	
	/*****/
	
	cout << "Hermano izquierdo luego de fusionar:\n";
	(*inodoFus).imprimirBasico();
	
	cout << "Nodo padre luego de fusionar:\n";
	(*inodo).imprimirBasico();
	
	cout << "Nodo con underflow luego de fusionar:\n";
	(*inodoUnd).imprimirBasico();
	
	if (!(*inodoFus).quedoEnUnderflow(50)){
		cout << "El hermano izq. quedó en estado válido\n";
	}
	
	if (!(*inodo).quedoEnUnderflow(50)){
		cout << "El padre quedó en estado válido\n";
	}
	
	if ((*inodoUnd).getNReg() == 0){
		cout << "El nodo que tenía underflow quedó vacío (se pasó todo al izquierdo)\n";
	}			
	
	delete inodoFus;
	delete inodo;
	delete inodoUnd;			
	
}		

void testFusionarNodoIndiceConDerecho(){


	///////////////// NODO INDICE DERECHO (para fusionar) //////////////////

	///// 1er reg


	char clave1 [] = "G";
	
	ClaveString* c1 = new ClaveString();
	(*c1).setClave(clave1);
		

	RegIndice<ClaveString,DatoInt>* reg1 = new RegIndice<ClaveString,DatoInt>();

	(*reg1).setClave(c1);
	
	
	
	///// 2do reg

	char clave2 [] = "H";
	
	ClaveString* c2 = new ClaveString();
	(*c2).setClave(clave2);
	

	RegIndice<ClaveString,DatoInt>* reg2 = new RegIndice<ClaveString,DatoInt>();

	(*reg2).setClave(c2);



	///// 3er reg
	
	char clave3 [] = "I";
	
	ClaveString* c3 = new ClaveString();
	(*c3).setClave(clave3);
	


	RegIndice<ClaveString,DatoInt>* reg3 = new RegIndice<ClaveString,DatoInt>();

	(*reg3).setClave(c3);

	
	///// 4to reg
	
	char clave5 [] = "J";
	
	ClaveString* c5 = new ClaveString();
	(*c5).setClave(clave5);
		

	RegIndice<ClaveString,DatoInt>* reg5 = new RegIndice<ClaveString,DatoInt>();

	(*reg5).setClave(c5);


				
	// CREO EL NODO INDICE CON LOS REG reg1, reg2, reg3 y reg5

	NodoIndice<ClaveString,DatoInt>* inodoFus = new NodoIndice<ClaveString,DatoInt>();

	(*inodoFus).setNivel(1);

	(*inodoFus).agregarNHijo(8);

	(*inodoFus).insertarRegEHijo(reg1,1);
	(*inodoFus).insertarRegEHijo(reg2,5);
	(*inodoFus).insertarRegEHijo(reg3,9);	
	(*inodoFus).insertarRegEHijo(reg5,6);	



	///////////////// NODO INDICE CON UNDERFLOW //////////////////

	///// 1er reg


	char clave4 [] = "E";
	
	ClaveString* c4 = new ClaveString();
	(*c4).setClave(clave4);
	


	RegIndice<ClaveString,DatoInt>* reg4 = new RegIndice<ClaveString,DatoInt>();

	(*reg4).setClave(c4);


				
	// CREO EL NODO DE INDICE CON EL REG reg4

	NodoIndice<ClaveString,DatoInt>* inodoUnd = new NodoIndice<ClaveString,DatoInt>();

	(*inodoUnd).setNivel(1);

	(*inodoUnd).agregarNHijo(2);

	(*inodoUnd).insertarRegEHijo(reg4,10);
		
		
		
///////////////// NODO ÍNDICE PADRE //////////////////

	///// 1er reg

	char clave6 [] = "D";
	
	ClaveString* c6 = new ClaveString();
	
	(*c6).setClave(clave6);

	RegIndice<ClaveString,DatoInt>* reg6 = new RegIndice<ClaveString,DatoInt>();

	(*reg6).setClave(c6);

	
	///// 2do reg

	char clave7 [] = "F";
	
	ClaveString* c7 = new ClaveString();
	
	(*c7).setClave(clave7);

	RegIndice<ClaveString,DatoInt>* reg7 = new RegIndice<ClaveString,DatoInt>();

	(*reg7).setClave(c7);
	
	
	///// 3er reg

	char clave8 [] = "K";
	
	ClaveString* c8 = new ClaveString();
	
	(*c8).setClave(clave8);

	RegIndice<ClaveString,DatoInt>* reg8 = new RegIndice<ClaveString,DatoInt>();

	(*reg8).setClave(c8);


	///// 4to reg

	char clave9 [] = "L";
	
	ClaveString* c9 = new ClaveString();
	
	(*c9).setClave(clave9);

	RegIndice<ClaveString,DatoInt>* reg9 = new RegIndice<ClaveString,DatoInt>();

	(*reg9).setClave(c9);	
	


	//CREO EL NODO ÍNDICE CON LOS REGISTROS reg6, reg7 y reg8

	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	(*inodo).setNivel(2);

	(*inodo).agregarNHijo(1);

	(*inodo).insertarRegEHijo(reg6,2);
	(*inodo).insertarRegEHijo(reg7,3);
	(*inodo).insertarRegEHijo(reg8,4);	
	(*inodo).insertarRegEHijo(reg9,5);
	
/*** Impresión de los nodos inicialmente ***/

	if ((*inodoUnd).quedoEnUnderflow(50)){
		cout << "El siguiente nodo está en underflow para un bloque de tamaño 50\n";
	}
	(*inodoUnd).imprimirBasico();		
	
	cout << "Nodo padre de ambos:\n";
	(*inodo).imprimirBasico();
	
			
	cout << "Hermano derecho fusionar:\n";	
	(*inodoFus).imprimirBasico();		
	
	
/********************************************/

	/*** FUSIONAMOS **/
	(*inodoUnd).fusionarConDerecho(inodoFus, inodo);	
	/*****/
	
	cout << "Nodo con underflow luego de fusionar:\n";
	(*inodoUnd).imprimirBasico();	
	
	
	cout << "Nodo padre luego de fusionar:\n";
	(*inodo).imprimirBasico();	
	
	cout << "Hermano derecho luego de fusionar:\n";
	(*inodoFus).imprimirBasico();
	
	
	if (!(*inodoUnd).quedoEnUnderflow(50)){
		cout << "El nodo que tenía underflow quedó en estado válido\n";
	}
	
	if (!(*inodo).quedoEnUnderflow(50)){
		cout << "El padre quedó en estado válido\n";
	}
	
	if ((*inodoFus).getNReg() == 0){
		cout << "El hermano derecho quedó vacío (se pasó todo al izquierdo)\n";
	}			
	
	delete inodoUnd;
	delete inodo;
	delete inodoFus;			
	
	
	
}

void testNoPuedeBalancearDatosConIzquierdo(){
	
/*** Vemos un caso donde si se quiere balancear con el hermano se lo
 *** deja en estado de underflow ***/

	/*** HERMANO IZQ (NO DEBERÍA PODER BALANCEAR) ***/


	/// Primer reg
	ClaveString* c1 = new ClaveString();
	c1->setClave("A");
		
	RegDatos<ClaveString,DatoInt>* r1 = new RegDatos<ClaveString,DatoInt>();	
	r1->setClave(c1);
	
	
	NodoDatos<ClaveString,DatoInt>* nodoBal = new NodoDatos<ClaveString,DatoInt>();
	nodoBal->insertarRegOrdenado(r1);


	
	/*** NODO PADRE ***/
	
	/// Primer reg
	ClaveString* c3 = new ClaveString();
	c3->setClave("C");
	
	RegIndice<ClaveString,DatoInt>* r3 = new RegIndice<ClaveString,DatoInt>();
	r3->setClave(c3);
	
	/// Segundo reg
	ClaveString* c4 = new ClaveString();
	c4->setClave("E");
	
	RegIndice<ClaveString,DatoInt>* r4 = new RegIndice<ClaveString,DatoInt>();
	r4->setClave(c4);
	
	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	inodo->insertarRegOrdenado(r3);
	inodo->insertarRegOrdenado(r4);
	
	
	/*** NODO CON UNDERFLOW ***/
	
	NodoDatos<ClaveString,DatoInt>* nodoUnd = new NodoDatos<ClaveString,DatoInt>();
	
	if(!nodoBal->quedoEnUnderflow(30)){
		cout << "El hermano derecho está en estado válido para nodos de tam. 30\n";
	}
	if(!inodo->quedoEnUnderflow(30)){
		cout << "El padre de ambos está en estado válido para nodos de tam. 30\n";
	}
	if (nodoUnd->quedoEnUnderflow(30)){
		cout << "Hijo derecho con underflow para nodos de tam. 30\n";
	}			

	if (!nodoUnd->puedeBalancear(nodoBal, inodo, 0, 30)){
		cout << "No se puede balancear con el izquierdo porque se lo dejaría en underflow; OK\n";
	}	

	delete nodoBal;
	delete inodo;
	delete nodoUnd;
	
}	

void testNoPuedeBalancearDatosConDerecho(){

	/*** HERMANO DCHO. (NO DEBERÍA PODER BALANCEAR) ***/

	/// Primer reg
	ClaveString* c1 = new ClaveString();
	c1->setClave("A");
		
	RegDatos<ClaveString,DatoInt>* r1 = new RegDatos<ClaveString,DatoInt>();	
	r1->setClave(c1);
	
	NodoDatos<ClaveString,DatoInt>* nodoBal = new NodoDatos<ClaveString,DatoInt>();
	nodoBal->insertarRegOrdenado(r1);


	
	/*** NODO PADRE ***/
	
	/// Primer reg
	ClaveString* c3 = new ClaveString();
	c3->setClave("A");
	
	RegIndice<ClaveString,DatoInt>* r3 = new RegIndice<ClaveString,DatoInt>();
	r3->setClave(c3);
	
	/// Segundo reg
	ClaveString* c4 = new ClaveString();
	c4->setClave("C");
	
	RegIndice<ClaveString,DatoInt>* r4 = new RegIndice<ClaveString,DatoInt>();
	r4->setClave(c4);
	
	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	inodo->insertarRegOrdenado(r3);
	inodo->insertarRegOrdenado(r4);
	
	
	/*** NODO CON UNDERFLOW ***/
	
	NodoDatos<ClaveString,DatoInt>* nodoUnd = new NodoDatos<ClaveString,DatoInt>();
	
	if (nodoUnd->quedoEnUnderflow(30)){
		cout << "Hijo derecho con underflow para nodos de tam. 30\n";
	}			

	if(!inodo->quedoEnUnderflow(30)){
		cout << "El padre de ambos está en estado válido para nodos de tam. 30\n";
	}

	if(!nodoBal->quedoEnUnderflow(30)){
		cout << "El hermano derecho está en estado válido para nodos de tam. 30\n";
	}

	if (!nodoUnd->puedeBalancear(nodoBal, inodo, 1, 30)){
		cout << "No se puede balancear con el derecho porque se lo dejaría en underflow; OK\n";
	}	

	delete nodoBal;
	delete inodo;
	delete nodoUnd;
		
	
	
}	

void testNoPuedeBalancearIndiceConIzquierdo(){

/*** Vemos un caso donde si se quiere balancear con el hermano se lo
 *** deja en estado de underflow ***/

	/*** HERMANO IZQ (NO DEBERÍA PODER BALANCEAR) ***/


	/// Primer reg
	ClaveString* c1 = new ClaveString();
	c1->setClave("A");
		
	RegIndice<ClaveString,DatoInt>* r1 = new RegIndice<ClaveString,DatoInt>();	
	r1->setClave(c1);
	
	
	NodoIndice<ClaveString,DatoInt>* nodoBal = new NodoIndice<ClaveString,DatoInt>();
	nodoBal->insertarRegOrdenado(r1);


	
	/*** NODO PADRE ***/
	
	/// Primer reg
	ClaveString* c3 = new ClaveString();
	c3->setClave("C");
	
	RegIndice<ClaveString,DatoInt>* r3 = new RegIndice<ClaveString,DatoInt>();
	r3->setClave(c3);
	
	/// Segundo reg
	ClaveString* c4 = new ClaveString();
	c4->setClave("E");
	
	RegIndice<ClaveString,DatoInt>* r4 = new RegIndice<ClaveString,DatoInt>();
	r4->setClave(c4);
	
	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	inodo->insertarRegOrdenado(r3);
	inodo->insertarRegOrdenado(r4);
	
	
	/*** NODO CON UNDERFLOW ***/
	
	NodoIndice<ClaveString,DatoInt>* nodoUnd = new NodoIndice<ClaveString,DatoInt>();
	
	if(!nodoBal->quedoEnUnderflow(30)){
		cout << "El hermano derecho está en estado válido para nodos de tam. 30\n";
	}
	if(!inodo->quedoEnUnderflow(30)){
		cout << "El padre de ambos está en estado válido para nodos de tam. 30\n";
	}
	if (nodoUnd->quedoEnUnderflow(30)){
		cout << "Hijo derecho con underflow para nodos de tam. 30\n";
	}			

	if (!nodoUnd->puedeBalancear(nodoBal, inodo, 0, 30)){
		cout << "No se puede balancear con el izquierdo porque se lo dejaría en underflow; OK\n";
	}	

	delete nodoBal;
	delete inodo;
	delete nodoUnd;	
	
}	

void testNoPuedeBalancearIndiceConDerecho(){

	/*** HERMANO DCHO. (NO DEBERÍA PODER BALANCEAR) ***/

	/// Primer reg
	ClaveString* c1 = new ClaveString();
	c1->setClave("B");
		
	RegIndice<ClaveString,DatoInt>* r1 = new RegIndice<ClaveString,DatoInt>();	
	r1->setClave(c1);
	
	NodoIndice<ClaveString,DatoInt>* nodoBal = new NodoIndice<ClaveString,DatoInt>();
	nodoBal->insertarRegOrdenado(r1);


	
	/*** NODO PADRE ***/
	
	/// Primer reg
	ClaveString* c3 = new ClaveString();
	c3->setClave("A");
	
	RegIndice<ClaveString,DatoInt>* r3 = new RegIndice<ClaveString,DatoInt>();
	r3->setClave(c3);
	
	/// Segundo reg
	ClaveString* c4 = new ClaveString();
	c4->setClave("C");
	
	RegIndice<ClaveString,DatoInt>* r4 = new RegIndice<ClaveString,DatoInt>();
	r4->setClave(c4);
	
	NodoIndice<ClaveString,DatoInt>* inodo = new NodoIndice<ClaveString,DatoInt>();
	inodo->insertarRegOrdenado(r3);
	inodo->insertarRegOrdenado(r4);
	
	
	/*** NODO CON UNDERFLOW ***/
	
	NodoIndice<ClaveString,DatoInt>* nodoUnd = new NodoIndice<ClaveString,DatoInt>();
	
	if (nodoUnd->quedoEnUnderflow(30)){
		cout << "Hijo derecho con underflow para nodos de tam. 30\n";
	}			

	if(!inodo->quedoEnUnderflow(30)){
		cout << "El padre de ambos está en estado válido para nodos de tam. 30\n";
	}

	if(!nodoBal->quedoEnUnderflow(30)){
		cout << "El hermano derecho está en estado válido para nodos de tam. 30\n";
	}

	if (!nodoUnd->puedeBalancear(nodoBal, inodo, 1, 30)){
		cout << "No se puede balancear con el derecho porque se lo dejaría en underflow; OK\n";
	}	

	delete nodoBal;
	delete inodo;
	delete nodoUnd;
			
	
}	

void testInsertarArbol(){
	
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,true);

	//// REG 1 /////
	ClaveString* clave1 = new ClaveString();	
	(*clave1).setClave("A");
	
	DatoInt* dato11 = new DatoInt();
	(*dato11).setDato(4);
	
	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();
	(*reg1).setClave(clave1);
	(*reg1).cargarDato(dato11);
	

	
	//// REG 2 ////
	ClaveString* clave2 = new ClaveString();	
	(*clave2).setClave("B");
	
	DatoInt* dato21 = new DatoInt();
	(*dato21).setDato(8);
	
	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();
	(*reg2).setClave(clave2);
	(*reg2).cargarDato(dato21);
	
	

	//// REG 3 ////
	ClaveString* clave3 = new ClaveString();	
	(*clave3).setClave("C");
	
	DatoInt* dato31 = new DatoInt();
	(*dato31).setDato(10);
	
	RegDatos<ClaveString,DatoInt>* reg3 = new RegDatos<ClaveString,DatoInt>();
	(*reg3).setClave(clave3);
	(*reg3).cargarDato(dato31);
	
	
	
	//// REG 4 ////
	ClaveString* clave4 = new ClaveString();	
	(*clave4).setClave("D");
	
	DatoInt* dato41 = new DatoInt();
	(*dato41).setDato(12);
	
	RegDatos<ClaveString,DatoInt>* reg4 = new RegDatos<ClaveString,DatoInt>();
	(*reg4).setClave(clave4);
	(*reg4).cargarDato(dato41);	
	
	
	//// REG 5 ////
	ClaveString* clave5 = new ClaveString();	
	(*clave5).setClave("E");
	
	DatoInt* dato51 = new DatoInt();
	(*dato51).setDato(14);
	
	RegDatos<ClaveString,DatoInt>* reg5 = new RegDatos<ClaveString,DatoInt>();
	(*reg5).setClave(clave5);
	(*reg5).cargarDato(dato51);	
	
	
	//// REG 6 ////
	ClaveString* clave6 = new ClaveString();	
	(*clave6).setClave("F");
	
	DatoInt* dato61 = new DatoInt();
	(*dato61).setDato(16);
	
	RegDatos<ClaveString,DatoInt>* reg6 = new RegDatos<ClaveString,DatoInt>();
	(*reg6).setClave(clave6);
	(*reg6).cargarDato(dato61);	
		
	
	//// REG 7 ///
	ClaveString* clave7 = new ClaveString();	
	(*clave7).setClave("G");
	
	DatoInt* dato71 = new DatoInt();
	(*dato71).setDato(18);
	
	RegDatos<ClaveString,DatoInt>* reg7 = new RegDatos<ClaveString,DatoInt>();
	(*reg7).setClave(clave7);
	(*reg7).cargarDato(dato71);	
	
	
	//// REG 8 ///
	ClaveString* clave8 = new ClaveString();	
	(*clave8).setClave("H");
	
	DatoInt* dato81 = new DatoInt();
	(*dato81).setDato(20);
	
	RegDatos<ClaveString,DatoInt>* reg8 = new RegDatos<ClaveString,DatoInt>();
	(*reg8).setClave(clave8);
	(*reg8).cargarDato(dato81);	
	
	
	//// REG 9 ///
	ClaveString* clave9 = new ClaveString();	
	(*clave9).setClave("I");
	
	DatoInt* dato91 = new DatoInt();
	(*dato91).setDato(22);
	
	RegDatos<ClaveString,DatoInt>* reg9 = new RegDatos<ClaveString,DatoInt>();
	(*reg9).setClave(clave9);
	(*reg9).cargarDato(dato91);			
	

	//// REG 10 ///
	ClaveString* clave10 = new ClaveString();	
	(*clave10).setClave("J");
	
	DatoInt* dato101 = new DatoInt();
	(*dato101).setDato(24);
	
	RegDatos<ClaveString,DatoInt>* reg10 = new RegDatos<ClaveString,DatoInt>();
	(*reg10).setClave(clave10);
	(*reg10).cargarDato(dato101);


	
		//// REG 11 ///
	ClaveString* clave11 = new ClaveString();	
	(*clave11).setClave("K");
	
	DatoInt* dato111 = new DatoInt();
	(*dato111).setDato(26);
	
	RegDatos<ClaveString,DatoInt>* reg11 = new RegDatos<ClaveString,DatoInt>();
	(*reg11).setClave(clave11);
	(*reg11).cargarDato(dato111);		
	
	
		//// REG 12 ///
	ClaveString* clave12 = new ClaveString();	
	(*clave12).setClave("L");
	
	DatoInt* dato121 = new DatoInt();
	(*dato121).setDato(28);
	
	RegDatos<ClaveString,DatoInt>* reg12 = new RegDatos<ClaveString,DatoInt>();
	(*reg12).setClave(clave12);
	(*reg12).cargarDato(dato121);		
	
	
	
		//// REG 13 ///
	ClaveString* clave13 = new ClaveString();	
	(*clave13).setClave("M");
	
	DatoInt* dato131 = new DatoInt();
	(*dato131).setDato(29);
	
	RegDatos<ClaveString,DatoInt>* reg13 = new RegDatos<ClaveString,DatoInt>();
	(*reg13).setClave(clave13);
	(*reg13).cargarDato(dato131);		
	
	
	
		//// REG 14 ///
	ClaveString* clave14 = new ClaveString();	
	(*clave14).setClave("N");
	
	DatoInt* dato141 = new DatoInt();
	(*dato141).setDato(30);
	
	RegDatos<ClaveString,DatoInt>* reg14 = new RegDatos<ClaveString,DatoInt>();
	(*reg14).setClave(clave14);
	(*reg14).cargarDato(dato141);		

	
		//// REG 15 ///
	ClaveString* clave15 = new ClaveString();	
	(*clave15).setClave("O");
	
	DatoInt* dato151 = new DatoInt();
	(*dato151).setDato(31);
	
	RegDatos<ClaveString,DatoInt>* reg15 = new RegDatos<ClaveString,DatoInt>();
	(*reg15).setClave(clave15);
	(*reg15).cargarDato(dato151);	
	
	vector<int> inserciones;
	
	int ins1 = (*a).insertarRegistro(reg1); inserciones.push_back(ins1);
	int ins2 = (*a).insertarRegistro(reg2); inserciones.push_back(ins2);
	int ins3 = (*a).insertarRegistro(reg3); inserciones.push_back(ins3);
	int ins4 = (*a).insertarRegistro(reg4); inserciones.push_back(ins4);
	int ins5 = (*a).insertarRegistro(reg5); inserciones.push_back(ins5);
	int ins6 = (*a).insertarRegistro(reg6); inserciones.push_back(ins6);
	int ins7 = (*a).insertarRegistro(reg7); inserciones.push_back(ins7);
	int ins8 = (*a).insertarRegistro(reg8); inserciones.push_back(ins8);
	int ins9 = (*a).insertarRegistro(reg9); inserciones.push_back(ins9);
	int ins10 = (*a).insertarRegistro(reg10); inserciones.push_back(ins10);
	int ins11 = (*a).insertarRegistro(reg11); inserciones.push_back(ins11);
	int ins12 = (*a).insertarRegistro(reg12); inserciones.push_back(ins12);
	int ins13 = (*a).insertarRegistro(reg13); inserciones.push_back(ins13);
	int ins14 = (*a).insertarRegistro(reg14); inserciones.push_back(ins14);
	int ins15 = (*a).insertarRegistro(reg15); inserciones.push_back(ins15);
	
	bool insertados = true;
	
	for (int i=0; i<(int)inserciones.size(); i++){
		if((inserciones[i]!=0) && (inserciones[i]!=1)){
			insertados = false;
		}
	}		
	
	if (insertados){
		cout << "Todos los registros fueron insertados con éxito\n";
	}	

	NodoIndice<ClaveString,DatoInt>* seis = new NodoIndice<ClaveString,DatoInt>();
	NodoIndice<ClaveString,DatoInt>* siete = new NodoIndice<ClaveString,DatoInt>();
	NodoIndice<ClaveString,DatoInt>* once = new NodoIndice<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* uno = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* dos = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* tres = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* cuatro = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* cinco = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* ocho = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* nueve = new NodoDatos<ClaveString,DatoInt>();
	NodoDatos<ClaveString,DatoInt>* diez = new NodoDatos<ClaveString,DatoInt>();
	
	ArchivoBloques<ClaveString,DatoInt>* arch = (*a).getArchivo();
	
	(*arch).leerBloque(seis, 6);
	(*arch).leerBloque(siete, 7);
	(*arch).leerBloque(once, 11);
	(*arch).leerBloque(uno, 1);
	(*arch).leerBloque(dos, 2);
	(*arch).leerBloque(tres, 3);
	(*arch).leerBloque(cuatro, 4);
	(*arch).leerBloque(cinco, 5);
	(*arch).leerBloque(ocho, 8);
	(*arch).leerBloque(nueve, 9);
	(*arch).leerBloque(diez, 10);


	NodoIndice<ClaveString,DatoInt>* raiz = (NodoIndice<ClaveString,DatoInt>*)((*a).getRaiz());
	
	cout << "/****** RAÍZ DEL ÁRBOL ******/\n";
	(*raiz).imprimirBasico();		
	cout << endl;
	
	cout << "  /****** NODO 6 ******/\n";
	(*seis).imprimirBasico();	
	cout << endl;
	
	cout << "  /****** NODO 7 ******/\n";				
	(*siete).imprimirBasico();
	cout << endl;	
	
	cout << "  /****** NODO 11 ******/\n";	
	(*once).imprimirBasico();
	cout << endl;	
	
	cout << "  /****** NODO 1 ******/\n";	
	(*uno).imprimirBasico();
	cout << endl;	
	
	cout << "  /****** NODO 2 ******/\n";	
	(*dos).imprimirBasico();
	cout << endl;
	
	cout << "  /****** NODO 3 ******/\n";	
	(*tres).imprimirBasico();
	cout << endl;	
	
	cout << "  /****** NODO 4 ******/\n";	
	(*cuatro).imprimirBasico();
	cout << endl;	
	
	cout << "  /****** NODO 5 ******/\n";	
	(*cinco).imprimirBasico();	
	cout << endl;	
	
	cout << "  /****** NODO 8 ******/\n";	
	(*ocho).imprimirBasico();	
	cout << endl;
	
	cout << "  /****** NODO 9 ******/\n";	
	(*nueve).imprimirBasico();
	cout << endl;	
	
	cout << "  /****** NODO 10 ******/\n";	
	(*diez).imprimirBasico();		
	cout << endl;
						
	
	/*
							0 : (6) G (7) M (11)
							
			
		6: (1) C (2) E		7: (4) I (5) K (8)			11: (9) O (10)
		
	
	1: AB	2: CD	3: EF	4: GH	5: IJ	8: KL		9: MN		10: O
	*/


	delete seis;
	delete siete;
	delete once;
	delete uno;
	delete dos;
	delete tres;
	delete cuatro;
	delete cinco;
	delete ocho;
	delete nueve;
	delete diez;

	delete (a); 		
	
	
}

void testBuscarInsertados(){
	
	// Abro el árbol que ya estaba creado
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,false);

	vector<ClaveString*> clavesARecup;
	vector<ClaveString*> clavesRecuperadas;

	//// REG 1 /////
	ClaveString* clave1 = new ClaveString();	
	(*clave1).setClave("A");
	
	RegDatos<ClaveString,DatoInt>* b1 = (*a).buscar(clave1);
	
	clavesARecup.push_back(clave1);
	clavesRecuperadas.push_back(b1->getClave());	
	
	//// REG 2 ////
	ClaveString* clave2 = new ClaveString();	
	(*clave2).setClave("B");

	RegDatos<ClaveString,DatoInt>* b2 = (*a).buscar(clave2);

	clavesARecup.push_back(clave2);
	clavesRecuperadas.push_back(b2->getClave());	

	//// REG 3 ////
	ClaveString* clave3 = new ClaveString();	
	(*clave3).setClave("C");

	 RegDatos<ClaveString,DatoInt>* b3 = (*a).buscar(clave3);
	 
	clavesARecup.push_back(clave3);
	clavesRecuperadas.push_back(b3->getClave());		 
	
	//// REG 4 ////
	ClaveString* clave4 = new ClaveString();	
	(*clave4).setClave("D");
	
	RegDatos<ClaveString,DatoInt>* b4 = (*a).buscar(clave4);
	
	clavesARecup.push_back(clave4);
	clavesRecuperadas.push_back(b4->getClave());		
		
	
	//// REG 5 ////
	ClaveString* clave5 = new ClaveString();	
	(*clave5).setClave("E");
	
	RegDatos<ClaveString,DatoInt>* b5 = (*a).buscar(clave5);	

	clavesARecup.push_back(clave5);
	clavesRecuperadas.push_back(b5->getClave());	

	
	//// REG 6 ////
	ClaveString* clave6 = new ClaveString();	
	(*clave6).setClave("F");
	
	RegDatos<ClaveString,DatoInt>* b6 = (*a).buscar(clave6);	
	
	clavesARecup.push_back(clave6);
	clavesRecuperadas.push_back(b6->getClave());		

	
	//// REG 7 ///
	ClaveString* clave7 = new ClaveString();	
	(*clave7).setClave("G");
	
	RegDatos<ClaveString,DatoInt>* b7 = (*a).buscar(clave7);	
	
	clavesARecup.push_back(clave7);
	clavesRecuperadas.push_back(b7->getClave());		

	
	//// REG 8 ///
	ClaveString* clave8 = new ClaveString();	
	(*clave8).setClave("H");
	
	RegDatos<ClaveString,DatoInt>* b8 = (*a).buscar(clave8);
		
	clavesARecup.push_back(clave8);
	clavesRecuperadas.push_back(b8->getClave());	
	
	
	//// REG 9 ///
	ClaveString* clave9 = new ClaveString();	
	(*clave9).setClave("I");
	
	RegDatos<ClaveString,DatoInt>* b9 = (*a).buscar(clave9);	

	clavesARecup.push_back(clave9);
	clavesRecuperadas.push_back(b9->getClave());	
	

	//// REG 10 ///
	ClaveString* clave10 = new ClaveString();	
	(*clave10).setClave("J");
	
	RegDatos<ClaveString,DatoInt>* b10 = (*a).buscar(clave10);	
	
	clavesARecup.push_back(clave10);
	clavesRecuperadas.push_back(b10->getClave());		

	
		//// REG 11 ///
	ClaveString* clave11 = new ClaveString();	
	(*clave11).setClave("K");
	
	RegDatos<ClaveString,DatoInt>* b11 = (*a).buscar(clave11);	
		
	clavesARecup.push_back(clave11);
	clavesRecuperadas.push_back(b11->getClave());			
	
	
		//// REG 12 ///
	ClaveString* clave12 = new ClaveString();	
	(*clave12).setClave("L");
	
	RegDatos<ClaveString,DatoInt>* b12 = (*a).buscar(clave12);	
	
	clavesARecup.push_back(clave12);
	clavesRecuperadas.push_back(b12->getClave());		

	
		//// REG 13 ///
	ClaveString* clave13 = new ClaveString();	
	(*clave13).setClave("M");
	
	RegDatos<ClaveString,DatoInt>* b13 = (*a).buscar(clave13);	
	
	clavesARecup.push_back(clave13);
	clavesRecuperadas.push_back(b13->getClave());		
	
	
		//// REG 14 ///
	ClaveString* clave14 = new ClaveString();	
	(*clave14).setClave("N");
	
	RegDatos<ClaveString,DatoInt>* b14 = (*a).buscar(clave14);	
	
	clavesARecup.push_back(clave14);
	clavesRecuperadas.push_back(b14->getClave());		

	
		//// REG 15 ///
	ClaveString* clave15 = new ClaveString();	
	(*clave15).setClave("O");
		
	RegDatos<ClaveString,DatoInt>* b15 = (*a).buscar(clave15);	
	
	clavesARecup.push_back(clave15);
	clavesRecuperadas.push_back(b15->getClave());	
			
			
	bool recuperados = true;
	
	for (size_t i=0; i<clavesRecuperadas.size(); i++){
		if (!((*(clavesARecup[i])) == (*(clavesRecuperadas[i])))){
			recuperados = false;
		}
	}
	
	if (recuperados == true){
		cout << "Todos los registros fueron recuperados exitosamente; OK\n";
	}					

	delete clave1;
	delete clave2;
	delete clave3;
	delete clave4;
	delete clave5;
	delete clave6;
	delete clave7;
	delete clave8;
	delete clave9;
	delete clave10;
	delete clave11;
	delete clave12;
	delete clave13;
	delete clave14;
	delete clave15;	
	
	delete b1;
	delete b2;
	delete b3;
	delete b4;
	delete b5;
	delete b6;
	delete b7;
	delete b8;
	delete b9;
	delete b10;
	delete b11;
	delete b12;
	delete b13;
	delete b14;
	delete b15;																											

	delete a;
}	

void testInsertarYQueNoSePueda(){
	
	// Abro el árbol que ya estaba creado
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,false);
	
	
	/*** Intentamos insertar un reg. que tenga tamaño inválido ***/
	
	ClaveString* clave1 = new ClaveString();
	clave1->setClave("T");
	
	DatoInt* dato1_1 = new DatoInt();
	dato1_1->setDato(120);
	
	DatoInt* dato1_2 = new DatoInt();
	dato1_2->setDato(289);
	
	DatoInt* dato1_3 = new DatoInt();
	dato1_3->setDato(222);
	
	DatoInt* dato1_4 = new DatoInt();
	dato1_4 ->setDato(277);
	
	RegDatos<ClaveString,DatoInt>* reg1 = new RegDatos<ClaveString,DatoInt>();	
	reg1->setClave(clave1);
	reg1->cargarDato(dato1_1);
	reg1->cargarDato(dato1_2);
	reg1->cargarDato(dato1_3);
	reg1->cargarDato(dato1_4);
	
	int ins1 = a->insertarRegistro(reg1);
	
	if(ins1 == 4){
		cout << "No se pudo insertar el registro porque es demasiado grande; OK\n";
		delete reg1;
	}	
	
	
	/*** Intentamos insertar un registro cuya clave ya está en el árbol ***/
	
	ClaveString* clave2 = new ClaveString();
	clave2->setClave("E");
	
	RegDatos<ClaveString,DatoInt>* reg2 = new RegDatos<ClaveString,DatoInt>();
	reg2->setClave(clave2);
	
	int ins2 = a->insertarRegistro(reg2);
	
	if (ins2 == 3){
		cout << "No se pudo insertar el registro porque cumple con la unicidad; OK\n";
		delete reg2;
	}	

	delete a;
}	

void testModificarRegistro(){
	
	// Abro el árbol que ya estaba creado
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,false);	
	
	/*** Inserto un registro sin datos ***/
	ClaveString* claveIns = new ClaveString();
	claveIns->setClave("P");
	
	RegDatos<ClaveString,DatoInt>* regIns = new RegDatos<ClaveString,DatoInt>();
	regIns->setClave(claveIns);
	
	a->insertarRegistro(regIns);
	
	/*** Agrego un dato ***/
	ClaveString* claveMod = new ClaveString();
	claveMod->setClave("P");
	
	DatoInt* dato = new DatoInt();
	dato->setDato(28);
	
	int modif = a->modificarRegistro(claveMod,dato);
	
	if ((modif == 0) || (modif == 1)){
		cout << "Registro modificado; OK\n";
	}
	
	/*** Recupero el registro modificado ***/
	
	RegDatos<ClaveString,DatoInt>* regModif = a->buscar(claveMod);
	
	if ((regModif->getDatos()).front()->getDato() == 28){
		cout << "Registro modificado correctamente; OK\n";
	}	
	
	delete regModif;
	delete claveMod;
	delete a;	
	
}	

void testModificarRegistroYQueNoSePueda(){
		
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,false);	
			
	DatoInt* dato = new DatoInt();
	dato->setDato(89);		
	
	/*** Intento modificar un registro con una clave que no está ***/	
	
	ClaveString* claveMod1 = new ClaveString();
	claveMod1->setClave("Z");
	
	int mod1 = a->modificarRegistro(claveMod1, dato);
	
	if (mod1 == 5){
		cout << "El registro no se modificó porque la clave pedida no existe; OK\n";
	}
	
	/*** Intento modificar un registro al cual si le agrego el dato es demasiado grande ***/
	
	ClaveString* claveMod2 = new ClaveString();
	claveMod2 ->setClave("J");
	
	DatoInt* dato2 = new DatoInt();
	dato2->setDato(43);
	
	a->modificarRegistro(claveMod2, dato2); //con este registro no pasa nada, se puede insertar
	
	int mod2 = a->modificarRegistro(claveMod2, dato); // este sí debería fallar
	
	if (mod2 == 4){
		cout << "El registro no se modificó porque el tamaño del registro excedería el permitido; OK\n";
	}	
		
	delete claveMod1;
	delete claveMod2;
	delete a;	
	
}	

void testBorrar(){
	
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,false);
	
	ClaveString* clave1 = new ClaveString();
	(*clave1).setClave("A");
	
	ClaveString* clave2 = new ClaveString();
	(*clave2).setClave("B");
	
	ClaveString* clave3 = new ClaveString();
	(*clave3).setClave("C");
	
	ClaveString* clave4 = new ClaveString();
	(*clave4).setClave("D");

	ClaveString* clave5 = new ClaveString();
	(*clave5).setClave("E");
	
	ClaveString* clave6 = new ClaveString();
	(*clave6).setClave("F");

	ClaveString* clave7 = new ClaveString();
	(*clave7).setClave("G");
	
	ClaveString* clave8 = new ClaveString();
	(*clave8).setClave("H");

	ClaveString* clave9 = new ClaveString();
	(*clave9).setClave("I");
	
	ClaveString* clave10 = new ClaveString();
	(*clave10).setClave("J");
	
	ClaveString* clave11 = new ClaveString();
	(*clave11).setClave("K");

	ClaveString* clave12 = new ClaveString();
	(*clave12).setClave("L");
	
	ClaveString* clave13 = new ClaveString();
	(*clave13).setClave("M");	

	ClaveString* clave14 = new ClaveString();
	(*clave14).setClave("N");		

	ClaveString* clave15 = new ClaveString();
	(*clave15).setClave("O");		
	
	vector<int> resultados;
	
	int b1 = (*a).borrar(clave1); resultados.push_back(b1);
	int b2 = (*a).borrar(clave2);resultados.push_back(b2);	
	int b3 = (*a).borrar(clave3);resultados.push_back(b3);		
	int b4 = (*a).borrar(clave4);resultados.push_back(b4);	
	int b5 = (*a).borrar(clave5);resultados.push_back(b5);				
	int b6 = (*a).borrar(clave6);resultados.push_back(b6);	
	int b7 = (*a).borrar(clave7);resultados.push_back(b7);		
	int b8 = (*a).borrar(clave8);resultados.push_back(b8);	
	int b9 = (*a).borrar(clave9);resultados.push_back(b9);	
	int b10 = (*a).borrar(clave10);resultados.push_back(b10);	
	int b11 = (*a).borrar(clave11);resultados.push_back(b11);			
	int b12 = (*a).borrar(clave12);	resultados.push_back(b12);		
	int b13 = (*a).borrar(clave13);	resultados.push_back(b13);	
	int b14 = (*a).borrar(clave14);	resultados.push_back(b14);		
	int b15 = (*a).borrar(clave15);	resultados.push_back(b15);					

	bool borrados = true;
	
	for (size_t i=0; i<resultados.size(); i++){
		if((resultados[i] != 0) && (resultados[i] != 1)){
			borrados = false;
		}
	}		

	if (borrados){
		cout << "Se han borrado los registros exitosamente; OK\n";
	}	

	delete clave1;
	delete clave2;
	delete clave3;	
	delete clave4;
	delete clave5;
	delete clave6;	 
	delete clave7;	
	delete clave8;		
	delete clave9;
	delete clave10;			
	delete clave11;			
	delete clave12;			
	delete clave13;	
	delete clave14;			
	delete clave15;	
	
	delete a;
	
}	

void testBorrarYQueNoSePueda(){
	
	ArbolBMas<ClaveString,DatoInt>* a = new ArbolBMas<ClaveString,DatoInt>("archivo.bin",40,false);
	
	/*** Intento borrar una clave que no está en el árbol ***/
	ClaveString* clave = new ClaveString();
	clave->setClave("U");
	
	int b = a->borrar(clave);
	
	if(b == 5){
		cout << "La clave solicitada para borrar es inexistente; OK\n";
	}		
	
	delete clave;
	delete a;
}	
